using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;

namespace TicTacToe.GS
{
    public class GameOption : GameStateFactory<GameOption>, IGameState
    {
        // Controls
        private Texture2D lblBoardSize;
        private Rectangle _BoardSizePosition;
        private Texture2D lblSize3x3;
        private Rectangle _Size3x3Position;
        private Texture2D lblSize6x6;
        private Rectangle _Size6x6Position;
        private Rectangle _SelectedBoardSizePosition;

        private Texture2D lblStyleTexure;
        private Rectangle _StyleTexturePosition;
        private Texture2D lblStyleClassic;
        private Rectangle _StyleClassicPosition;
        private Texture2D lblStyleModern;
        private Rectangle _StyleModernPosition;
        private Rectangle _SelectedStylePosition;

        private Texture2D lblNumToWin;
        private Rectangle _NumToWinPosition;
        private Texture2D lblThreeWin;
        private Rectangle _ThreeWinPosition;
        private Texture2D lblFiveWin;
        private Rectangle _FiveWinPosition;
        private Rectangle _SelectedNumToWinPosition;

        private Texture2D lblFirstPlayer;
        private Rectangle _FirstPlayerPosition;
        private Texture2D lblPlayerX;
        private Rectangle _PlayerXPosition;
        private Texture2D lblPlayerO;
        private Rectangle _PlayerOPosition;
        private Rectangle _SelectedPlayerPosition;

        private Texture2D lblBackButton;
        private Rectangle _BackButtonPosition;

        private Texture2D _Selected;

        // Propeties
        private BoardSize _BoardSize;
        private Style_Texture _StyleTexture;
        private TicTacToePlayer _FirstPlayer;
        private int _NumToWin;
        private bool _IsInitGraphics;

        // boolean value to specify that game need reset
        private bool _NeedReset = false;
        // boolean value to specify that game style changed
        private bool _StyleChanged = false;

        // Khong duoc de constructor la public
        public GameOption()
        {
            InitOption();
        }

        private void InitGraphics()
        {
            // board size
            lblBoardSize = _GamePlay.GetGameMain().Content.Load<Texture2D>("BoardSize_Text");
            _BoardSizePosition = new Rectangle(15, 15, lblBoardSize.Width, lblBoardSize.Height);
            lblSize3x3 = _GamePlay.GetGameMain().Content.Load<Texture2D>("BoardSize_3x3");
            _Size3x3Position = new Rectangle(30, 100, lblSize3x3.Width, lblSize3x3.Height);
            lblSize6x6 = _GamePlay.GetGameMain().Content.Load<Texture2D>("BoardSize_6x6");
            _Size6x6Position = new Rectangle(260, 100, lblSize6x6.Width, lblSize6x6.Height);

            // style texture
            lblStyleTexure = _GamePlay.GetGameMain().Content.Load<Texture2D>("StyleTexture");
            _StyleTexturePosition = new Rectangle(15, 170, lblStyleTexure.Width, lblStyleTexure.Height);
            lblStyleClassic = _GamePlay.GetGameMain().Content.Load<Texture2D>("StyleTexture_Classic");
            _StyleClassicPosition = new Rectangle(30, 260, lblStyleClassic.Width, lblStyleClassic.Height);
            lblStyleModern = _GamePlay.GetGameMain().Content.Load<Texture2D>("StyleTexture_Modern");
            _StyleModernPosition = new Rectangle(260, 260, lblStyleModern.Width, lblStyleModern.Height);

            // first player
            lblFirstPlayer = _GamePlay.GetGameMain().Content.Load<Texture2D>("FirstPlayer_Text");
            _FirstPlayerPosition = new Rectangle(15, 330, lblFirstPlayer.Width, lblFirstPlayer.Height);
            lblPlayerX = _GamePlay.GetGameMain().Content.Load<Texture2D>("FirstPlayer_X");
            _PlayerXPosition = new Rectangle(30, 420, lblPlayerX.Width, lblPlayerX.Height);
            lblPlayerO = _GamePlay.GetGameMain().Content.Load<Texture2D>("FirstPlayer_O");
            _PlayerOPosition = new Rectangle(260, 420, lblPlayerO.Width, lblPlayerO.Height);

            // back button
            lblBackButton = _GamePlay.GetGameMain().Content.Load<Texture2D>("TicTacToe_Back");
            _BackButtonPosition = new Rectangle(_GamePlay.GetSpriteBatch().GraphicsDevice.Viewport.Width / 2 - (lblBackButton.Width / 2), _GamePlay.GetSpriteBatch().GraphicsDevice.Viewport.Height - 95, lblBackButton.Width, lblBackButton.Height);

            // Num to win
            lblNumToWin = _GamePlay.GetGameMain().Content.Load<Texture2D>("NumToWin");
            _NumToWinPosition = new Rectangle(15, 490, lblNumToWin.Width, lblNumToWin.Height);
            lblThreeWin = _GamePlay.GetGameMain().Content.Load<Texture2D>("ThreePieceWin");
            _ThreeWinPosition = new Rectangle(30, 580, lblThreeWin.Width, lblThreeWin.Height);
            lblFiveWin = _GamePlay.GetGameMain().Content.Load<Texture2D>("FivePieceWin");
            _FiveWinPosition = new Rectangle(260, 580, lblFiveWin.Width, lblFiveWin.Height);

            // Selected
            _Selected = _GamePlay.GetGameMain().Content.Load<Texture2D>("Selected");
            if (_GamePlay.SizeOfBoard == BoardSize.Six_x_Six)
                SetSelectedPosition(ref _SelectedBoardSizePosition, _Size6x6Position);
            else
                SetSelectedPosition(ref _SelectedBoardSizePosition, _Size3x3Position);
            if (_FirstPlayer == TicTacToePlayer.PlayerX)
                SetSelectedPosition(ref _SelectedPlayerPosition, _PlayerXPosition);
            else
                SetSelectedPosition(ref _SelectedPlayerPosition, _PlayerOPosition);
            if (_GamePlay.StyleTexture == Style_Texture.Classic)
                SetSelectedPosition(ref _SelectedStylePosition, _StyleClassicPosition);
            else
                SetSelectedPosition(ref _SelectedStylePosition, _StyleModernPosition);
            if (((SinglePlay)_GamePlay).LogicOfGame.NumToWin == 3)
                SetSelectedPosition(ref _SelectedNumToWinPosition, _ThreeWinPosition);
            else
                SetSelectedPosition(ref _SelectedNumToWinPosition, _FiveWinPosition);
            _IsInitGraphics = true;
        }

        private void InitOption()
        {
            _BoardSize = (BoardSize)Enum.Parse(typeof(BoardSize), OptionSaver.Get(OptionSaver.BOARD_SIZE).ToString(), false);
            _StyleTexture = (Style_Texture)Enum.Parse(typeof(Style_Texture), OptionSaver.Get(OptionSaver.X_O_STYLE).ToString(), false);
            _FirstPlayer = (TicTacToePlayer)Enum.Parse(typeof(TicTacToePlayer), OptionSaver.Get(OptionSaver.PLAY_FIRST).ToString(), false);
            _NumToWin = int.Parse(OptionSaver.Get(OptionSaver.NUM_TO_WIN).ToString());
        }

        public void DrawControls()
        {
            if (!_IsInitGraphics)
                InitGraphics();

            _GamePlay.GetSpriteBatch().Draw(lblBoardSize, _BoardSizePosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblSize3x3, _Size3x3Position, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblSize6x6, _Size6x6Position, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblStyleTexure, _StyleTexturePosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblStyleClassic, _StyleClassicPosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblStyleModern, _StyleModernPosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblFirstPlayer, _FirstPlayerPosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblPlayerX, _PlayerXPosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblPlayerO, _PlayerOPosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblBackButton, _BackButtonPosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblNumToWin, _NumToWinPosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblThreeWin, _ThreeWinPosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(lblFiveWin, _FiveWinPosition, Color.White);

            _GamePlay.GetSpriteBatch().Draw(_Selected, _SelectedBoardSizePosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(_Selected, _SelectedStylePosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(_Selected, _SelectedPlayerPosition, Color.White);
            _GamePlay.GetSpriteBatch().Draw(_Selected, _SelectedNumToWinPosition, Color.White);
        }

        private void SetSelectedPosition(ref Rectangle des, Rectangle source)
        {
            des.X = source.X;
            des.Y = source.Y + source.Height;
            des.Width = source.Width;
            des.Height = source.Height;
        }

        public void HandleTouch(TouchLocation touch)
        {
            if (_Size3x3Position.Contains((int)touch.Position.X, (int)touch.Position.Y))
            {
                //if (_GamePlay.SizeOfBoard != BoardSize.Three_x_Three)
                {
                    SetSelectedPosition(ref _SelectedBoardSizePosition,_Size3x3Position);
                    _GamePlay.SizeOfBoard = BoardSize.Three_x_Three;
                    OptionSaver.Set(OptionSaver.BOARD_SIZE, _GamePlay.SizeOfBoard);
                    _NeedReset = true;
                }
            }
            else if (_Size6x6Position.Contains((int)touch.Position.X, (int)touch.Position.Y))
            {
                //if (_GamePlay.SizeOfBoard != BoardSize.Six_x_Six)
                {
                    SetSelectedPosition(ref _SelectedBoardSizePosition, _Size6x6Position);
                    _GamePlay.SizeOfBoard = BoardSize.Six_x_Six;
                    OptionSaver.Set(OptionSaver.BOARD_SIZE, _GamePlay.SizeOfBoard);
                    _NeedReset = true;
                }
            }
            else if (_PlayerOPosition.Contains((int)touch.Position.X, (int)touch.Position.Y))
            {
                //if (_FirstPlayer != TicTacToePlayer.PlayerO)
                {
                    SetSelectedPosition(ref _SelectedPlayerPosition, _PlayerOPosition);
                    _FirstPlayer = TicTacToePlayer.PlayerO;
                    OptionSaver.Set(OptionSaver.PLAY_FIRST, _FirstPlayer);
                    _NeedReset = true;
                }
            }
            else if (_PlayerXPosition.Contains((int)touch.Position.X, (int)touch.Position.Y))
            {
                //if (_FirstPlayer != TicTacToePlayer.PlayerX)
                {
                    SetSelectedPosition(ref _SelectedPlayerPosition, _PlayerXPosition);
                    _FirstPlayer = TicTacToePlayer.PlayerX;
                    OptionSaver.Set(OptionSaver.PLAY_FIRST, _FirstPlayer);
                    _NeedReset = true;
                }
            }
            else if ((_StyleClassicPosition.Contains((int)touch.Position.X, (int)touch.Position.Y)))
            {
                //if (_GamePlay.StyleTexture != Style_Texture.Classic)
                {
                    SetSelectedPosition(ref _SelectedStylePosition, _StyleClassicPosition);
                    _GamePlay.StyleTexture = Style_Texture.Classic;
                    OptionSaver.Set(OptionSaver.X_O_STYLE, _GamePlay.StyleTexture);
                    _StyleChanged = true;
                }
            }
            else if ((_StyleModernPosition.Contains((int)touch.Position.X, (int)touch.Position.Y)))
            {
                //if (_GamePlay.StyleTexture != Style_Texture.Modern)
                {
                    SetSelectedPosition(ref _SelectedStylePosition, _StyleModernPosition);
                    _GamePlay.StyleTexture = Style_Texture.Modern;
                    OptionSaver.Set(OptionSaver.X_O_STYLE, _GamePlay.StyleTexture);
                    _StyleChanged = true;
                }
            }
            else if (_ThreeWinPosition.Contains((int)touch.Position.X, (int)touch.Position.Y))
            {
                SetSelectedPosition(ref _SelectedNumToWinPosition, _ThreeWinPosition);
                ((SinglePlay)_GamePlay).LogicOfGame.NumToWin = 3;
                OptionSaver.Set(OptionSaver.NUM_TO_WIN, 3);
                _StyleChanged = true;
            }
            else if (_FiveWinPosition.Contains((int)touch.Position.X, (int)touch.Position.Y))
            {
                SetSelectedPosition(ref _SelectedNumToWinPosition, _FiveWinPosition);
                ((SinglePlay)_GamePlay).LogicOfGame.NumToWin = 5;
                OptionSaver.Set(OptionSaver.NUM_TO_WIN, 5);
                _StyleChanged = true;
            }
            else if (_BackButtonPosition.Contains((int)touch.Position.X, (int)touch.Position.Y))
            {
                if (_NeedReset)
                {
                    ((SinglePlay)_GamePlay).LoadOptionAndMakeNewLogic();
                    ((SinglePlay)_GamePlay).LoadBoardAnd_X_O();
                    _NeedReset = false;
                }
                if (_StyleChanged)
                {
                    ((SinglePlay)_GamePlay).Load_X_O();
                    _StyleChanged = false;
                }
                _GamePlay.SetScreen(Screen.Main);
            }
            else
            {
                // Touch nothing, do nothing
            }
        }

        public Screen GetScreen()
        {
            return Screen.Option;
        }

        public void SetGamePlay(GamePlay gp)
        {
            _GamePlay = gp;
            _GamePlay.SizeOfBoard = _BoardSize;
            _GamePlay.StyleTexture = _StyleTexture;
        }
    }
}
